package processes
import(
	"fmt"
	"net"
	"encoding/json"
	"encoding/binary"
	"ChatRoom/common/message"
	"ChatRoom/client/utils"
	"ChatRoom/client/model"

)

type UserProcess struct{

}


//写一个函数，完成登陆
func (this *UserProcess)Login(userId int, userPwd string)(err error){
	// //开始定协议
	// fmt.Printf("userId = %d, userPwd=%s\n",userId,userPwd)
	// return nil
	//1.连接服务器
	conn,err := net.Dial("tcp","localhost:8889")
	if err!=nil{
		fmt.Println("net.Dial err=",err)
		return
	}
	//2.准备通过conn发送消息给服务器
	var msg message.Message
	msg.Type = message.LoginMsgType

	//3.创建一个LoginMes 结构体
	var loginMsg message.LoginMsg
	loginMsg.UserId = userId
	loginMsg.UserPwd = userPwd
	
	//4.将loginMsg序列化,序列化后得到的是切片
	data,err := json.Marshal(loginMsg)
	if err!=nil{
		fmt.Println("json.Marshal err=",err)
		return
	}
	//5.将切片data强转为string类型并赋值给msg.Data
	msg.Data = string(data)

	//6.将msg序列化
	data,err = json.Marshal(msg)
	if err!=nil{
		fmt.Println("json.Marshal err=",err)
		return
	}

	//7.到这个时候，data就是我们要发送的消息
	//7.1先把data的长度发送给服务器
	//先获取到data的长度-》再转成一个表示长度的byte切片
	var pkgLen uint32
	pkgLen = uint32(len(data))
	var buf [4]byte
	binary.BigEndian.PutUint32(buf[:4],pkgLen)
	//发送长度
	n,err :=conn.Write(buf[:4])
	if n!=4||err!=nil {
		fmt.Println("conn.Write(header),err=",err)
		return
	}
	//延时关闭
	//defer conn.Close()

	// fmt.Println("客户端发送消息长度成功,len=",len(data))
	 fmt.Println("数据内容为：data=",string(data))
	_,err =conn.Write(data)
	if err!=nil {
		fmt.Println("conn.Write(date),err=",err)
		return
	}

	// //处理服务器端返回的消息
	// time.Sleep(5*time.Second)
	// fmt.Println("休眠了20秒")
	//读取服务器返回的登陆返回消息
	tf := &utils.Transfer{
		Conn:conn,
	}
	msg,err = tf.ReadPkg()
	if err!=nil {
		fmt.Println("readPkg(conn),err=",err)
		return
	}

	//将msg的Data部分反序列化成LoginResMes
	var loginResMsg message.LoginResMsg
	err = json.Unmarshal([]byte(msg.Data),&loginResMsg)
	if err!=nil {
		fmt.Println("json.Unmarshal(msg.Data,loginResMsg),err=",err)
		return
	}
	if loginResMsg.Code==200{
		fmt.Println("登陆成功")
		
		// //客户端启动一个协程，如果服务器推送消息给客户端，通过该协程来接收
		go ServerProcessMsg(conn)
		//循环显示登陆成功后的菜单
		ShowMainTable()
	}else{
		fmt.Println(loginResMsg.Error)
	}
	return
}


//写一个函数，完成登陆
func (this *UserProcess)Register(userId int, userPwd string,userName string)(err error){
	// //开始定协议
	// fmt.Printf("userId = %d, userPwd=%s\n",userId,userPwd)
	// return nil
	//1.连接服务器
	conn,err := net.Dial("tcp","localhost:8889")
	if err!=nil{
		fmt.Println("net.Dial err=",err)
		return
	}
	//2.准备通过conn发送消息给服务器
	var msg message.Message
	msg.Type = message.RegisterMsgType

	//3.创建一个registerMsg 结构体
	var registerMsg message.RegisterMsg
	registerMsg.User = model.User{
		UserId:userId,
		UserPwd:userPwd,
		UserName:userName,
	}
	
	//4.将registerMsg序列化,序列化后得到的是切片
	data,err := json.Marshal(registerMsg)
	if err!=nil{
		fmt.Println("json.Marshal err=",err)
		return
	}
	//5.将切片data强转为string类型并赋值给msg.Data
	msg.Data = string(data)

	//6.将msg序列化
	data,err = json.Marshal(msg)
	if err!=nil{
		fmt.Println("json.Marshal err=",err)
		return
	}
	//创建一个Transfer实例
	tf := &utils.Transfer{
		Conn:conn,
	}
	//发送data数据给服务器

	err = tf.WritePkg(data)
	if err!=nil{
		fmt.Println("tf.WritePkg err=",err)
		return
	}
	msg,err = tf.ReadPkg()
	if err!=nil{
		fmt.Println("tf.readPkg err=",err)
		return
	}

	//将msg的Data部分反序列化成LoginResMes
	var registerResMsg message.RegisterResMsg
	err = json.Unmarshal([]byte(msg.Data),&registerResMsg)
	if err!=nil {
		fmt.Println("json.Unmarshal(msg.Data,registerResMsg),err=",err)
		return
	}
	if registerResMsg.Code==200{
		fmt.Println("注册成功")
	}else{
		fmt.Println(registerResMsg.Error)
	}
	return
}